#pragma once

#include <wx/wx.h>
#include <wx/hashmap.h>
#include <wx/filename.h>
#include <wx/bitmap.h>
#include <wx/dir.h>


/**
 * Optimized wxArtProvier
 */
WX_DECLARE_STRING_HASH_MAP(wxBitmap*, ThemeBmpHash);

/**
 * Theme dir hash map
 */
WX_DECLARE_STRING_HASH_MAP(wxFileName*, ThemeDirHash);


class IThemeable {
public:
    virtual void reTheme() = 0;
};


class ThemeManager {
public:
	virtual ~ThemeManager() {
		wxLogMessage(_T("ThemeManager::~ThemeManager"));
	}
	
    /**
     * Get global theme manager object.
     * 
     * @return ThemeManager*
     */
    static ThemeManager& get() {
        if(_theme_mgr==NULL) {
        	_theme_mgr = new ThemeManager();
        }

        return *_theme_mgr;
    }
    
    bool reTheme(const wxString& theme_name);

    bool doregister(IThemeable& themeable_obj);

    bool unregister(IThemeable& themeable_obj);

    
    /** 
     * Will auto load if bmp does not exists, otherwise, just return 
     * the reference of the bmp object already loaded. 
     *  
     * @param bmp_rpath PNG bitmap file path, relative to the Global
     *                 Resource Path.
     * 
     * @return wxBitmap&
     */
    wxBitmap& get_bitmap(const wxString& bmp_name);

    
    /**
     * Unload bmp, just to save memory when you don't need the bmp 
     * specify the by bmp_rpath. bmp will auto load again when you 
     * call get_bitmap method next time. 
     *  
     * @param bmp_rpath
     * 
     * @return bool
     */
    bool unload_bitmap(const wxString& bmp_rpath);

    /** Get themes directory.
     *  Return the directory for the application themes:
     *    Unix: prefix/share/Daodict/theme
     *    Windows: the directory where the executable file is located\theme
     *    Mac: Daodict.app/Contents/SharedSupport bundle/theme
     */
    wxFileName themes_dir;
    
protected:
    
    static ThemeManager* _theme_mgr;

    wxFileName _current_theme_dir;
    
    ThemeBmpHash _bmp_hash;
    ThemeDirHash _theme_dir_hash;
    
    /**
     * Init theme dirs.
     */
    void _init_theme_dirs();

    /**
     * Init theme specified in configuration file.
     */
    void _set_current_theme(const wxString& theme_name);

private:
    ThemeManager();
};


class ThemeDirsTraverser : public wxDirTraverser {
public: 
    ThemeDirsTraverser(wxArrayString& dirs) : _dirs(dirs) {
    }
     
    virtual wxDirTraverseResult OnDir(const wxString& entry) {
        //wxMessageBox(entry);
        this->_dirs.Add(entry);
        return wxDIR_IGNORE;
    } 
    
    virtual wxDirTraverseResult OnFile(const wxString& entry) {
        //wxMessageBox(entry);
        return wxDIR_CONTINUE;
    } 
private: 
    wxArrayString& _dirs;
}; 

